# -*- Makefile -*-
#*****************************************************************************
#
# DESCRIPTION: Verilator: Makefile for verilog source
#
# Code available from: https://verilator.org
#
#*****************************************************************************
#
# Copyright 2003-2025 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
#
#****************************************************************************/

#### Start of system configuration section. ####

# Unfortunately configure uses relative paths, and this makefile is called
# from a level lower, so we need to move up if it's relative, not if absolute.
config_srcdir = @srcdir@
ifeq ($(config_srcdir),.)
  srcdir = ..
else  # Run an experiment
  ifeq ($(wildcard $(config_srcdir)/../Makefile_obj.in),)
    srcdir = $(config_srcdir)
  else
    srcdir = $(config_srcdir)/..
  endif
endif

incdir = $(srcdir)/../include
# Bldsrc may differ from srcdir if configure wan't run from the kit top
bldsrc = ..

# Programs
CC = false # Everything is built as C++ via CXX
CXX = @CXX@
LINK = @CXX@
LEX = @LEX@
LFLAGS = -d
PYTHON3 = @PYTHON3@
YACC = @YACC@
OBJCACHE ?= @OBJCACHE@

prefix = @prefix@

# Directory in which to install data across multiple architectures
datarootdir = @datarootdir@

# Directory in which to install package-specific files
# Generally ${prefix}/share/verilator
pkgdatadir = @pkgdatadir@

# Compile options
CFG_WITH_CCWARN = @CFG_WITH_CCWARN@
CFG_WITH_DEFENV = @CFG_WITH_DEFENV@
CFG_WITH_DEV_GCOV = @CFG_WITH_DEV_GCOV@
CFG_WITH_SOLVER = @CFG_WITH_SOLVER@
CPPFLAGS += @CPPFLAGS@
CFLAGS += @CFLAGS@
CXXFLAGS += @CXXFLAGS@
LDFLAGS += @LDFLAGS@
EXEEXT = @EXEEXT@
CFG_CXXFLAGS_SRC = @CFG_CXXFLAGS_SRC@
CFG_CXXFLAGS_PARSER = @CFG_CXXFLAGS_PARSER@
# Compiler flags that turn on extra warnings
CFG_CXXFLAGS_WEXTRA = @CFG_CXXFLAGS_WEXTRA@
CFG_LDFLAGS_SRC = @CFG_LDFLAGS_SRC@
CFG_LIBS = @CFG_LIBS@
CFG_CXXFLAGS_PCH = -x c++-header
# Compiler option to put in front of filename to read precompiled header
CFG_CXXFLAGS_PCH_I = @CFG_CXXFLAGS_PCH_I@
# Compiler's filename prefix for precompiled headers, .gch if clang, empty if GCC
CFG_GCH_IF_CLANG = @CFG_GCH_IF_CLANG@

#### End of system configuration section. ####

VPATH += . $(bldsrc) $(srcdir)
TGT = ../../verilator_bin$(EXEEXT)

#################
ifeq ($(VL_NOOPT),1)
  CPPFLAGS += -O0
else ifeq ($(VL_DEBUG),)
  # Optimize
  CPPFLAGS += @CFG_CXXFLAGS_OPT@
else
  # Debug
  CPPFLAGS += @CFG_CXXFLAGS_DBG@ -DVL_DEBUG -D_GLIBCXX_DEBUG
  LDFLAGS += @CFG_LDFLAGS_DBG@
endif
#################

#LIBS += -ldl
#CCMALLOC = /usr/local/lib/ccmalloc-gcc.o -lccmalloc -ldl

# -lfl not needed as Flex invoked with %nowrap option
LIBS = $(CFG_LIBS) -lm

CPPFLAGS += -DVERILATOR_INTERNAL_
CPPFLAGS += -MMD
CPPFLAGS += -I. -I$(bldsrc) -I$(srcdir) -I$(incdir) -I../../include
#CPPFLAGS += -DVL_LEAK_CHECKS  # If running valgrind or other hunting tool
CPPFLAGS += -MP # Only works on recent GCC versions
ifeq ($(CFG_WITH_CCWARN),yes)  # Local... Else don't burden users
  CPPFLAGS += -W -Wall $(CFG_CXXFLAGS_WEXTRA) $(CFG_CXXFLAGS_SRC) -Werror
  #CPPFLAGS += -pedantic-errors
else
  CPPFLAGS += $(CFG_CXXFLAGS_SRC)
endif
LDFLAGS += $(CFG_LDFLAGS_SRC)

CPPFLAGSWALL = $(CPPFLAGS)
CPPFLAGSPARSER = $(CPPFLAGS) $(CFG_CXXFLAGS_PARSER)

# Allow RPM builds to specify hardcoded data directories
# To do this:
ifeq ($(CFG_WITH_DEFENV),yes)
  CPPFLAGS += -DDEFENV_SYSTEMC=\"$(SYSTEMC)\"
  CPPFLAGS += -DDEFENV_SYSTEMC_ARCH=\"$(SYSTEMC_ARCH)\"
  CPPFLAGS += -DDEFENV_SYSTEMC_INCLUDE=\"$(SYSTEMC_INCLUDE)\"
  CPPFLAGS += -DDEFENV_SYSTEMC_LIBDIR=\"$(SYSTEMC_LIBDIR)\"
  ifeq ($(VERILATOR_ROOT),)  # Use what we're given, or intuit
    CPPFLAGS += -DDEFENV_VERILATOR_ROOT=\"$(pkgdatadir)\"
  else
    CPPFLAGS += -DDEFENV_VERILATOR_ROOT=\"$(VERILATOR_ROOT)\"
  endif
  ifneq ($(CFG_WITH_SOLVER),no)
    CPPFLAGS += -DDEFENV_VERILATOR_SOLVER='"$(CFG_WITH_SOLVER)"'
  else
    ifneq ($(VERILATOR_SOLVER),)
      CPPFLAGS += -DDEFENV_VERILATOR_SOLVER='"$(VERILATOR_SOLVER)"'
    endif
  endif
endif

# Object file specific options
CXXFLAGSOBJ =
ifeq ($(CFG_WITH_DEV_GCOV),yes)
# Adding '-fkeep-inline-functions' to all files slows down coverage collection
# during 'make test' by ~3x. This option is only useful to make sure that
# 'inline' functions defined in headers are actually emitted so they show up as
# uncovered if they are never called, so instead of adding it everywhere, use
# only on a few files that together pull in most of the headers.
Verilator.o V3Dfg.o: CXXFLAGSOBJ += -fkeep-inline-functions
endif

HEADERS = $(wildcard V*.h v*.h)

ASTGEN = $(srcdir)/astgen
BISONPRE = $(srcdir)/bisonpre
FLEXFIX = $(srcdir)/flexfix
VLCOVGEN = $(srcdir)/vlcovgen

# BISON_DEBUG = -Wcounterexamples

######################################################################
# CCACHE flags (via environment as no command line option available)
CCACHE_SLOPPINESS ?= pch_defines,time_macros
export CCACHE_SLOPPINESS

######################################################################
#### Top level

all: make_info $(TGT)

make_info:
	@echo "      Compile flags: " $(CXX) ${CFLAGS} ${CXXFLAGS} ${CPPFLAGS}

clean mostlyclean distclean maintainer-clean::
	-rm -f *.o *.d *_gen_*
	-rm -f *__gen*
	-rm -f obj_* .objcache*

distclean maintainer-clean:: clean

maintainer-clean::

maintainer-copy::

#### Top executable

RAW_OBJS = \
  V3Const__gen.o \
  V3Error.o \
  V3FileLine.o \
  V3Graph.o \
  V3GraphAcyc.o \
  V3GraphAlg.o \
  V3GraphPathChecker.o \
  V3GraphTest.o \
  V3Hash.o \
  V3OptionParser.o \
  V3Os.o \
  V3ParseGrammar.o \
  V3ParseImp.o \
  V3ParseLex.o \
  V3PreProc.o \
  V3PreShell.o \
  V3String.o \
  V3ThreadPool.o \
  V3Waiver.o \
  Verilator.o \

RAW_OBJS_PCH_ASTMT = \
  V3Ast.o \
  V3AstNodes.o \
  V3Broken.o \
  V3Control.o \
  V3EmitCBase.o \
  V3EmitCConstPool.o \
  V3EmitCFunc.o \
  V3EmitCHeaders.o \
  V3EmitCImp.o \
  V3EmitCInlines.o \
  V3EmitCPch.o \
  V3EmitV.o \
  V3File.o \
  V3FuncOpt.o \
  V3Global.o \
  V3Hasher.o \
  V3Number.o \
  V3Options.o \
  V3Stats.o \
  V3StatsReport.o \
  V3VariableOrder.o \

RAW_OBJS_PCH_ASTNOMT = \
  V3Active.o \
  V3ActiveTop.o \
  V3Assert.o \
  V3AssertPre.o \
  V3Begin.o \
  V3Branch.o \
  V3CCtors.o \
  V3CUse.o \
  V3Case.o \
  V3Cast.o \
  V3Cfg.o \
  V3CfgBuilder.o \
  V3CfgLiveVariables.o \
  V3Class.o \
  V3Clean.o \
  V3Clock.o \
  V3Combine.o \
  V3Common.o \
  V3Coverage.o \
  V3CoverageJoin.o \
  V3Dead.o \
  V3Delayed.o \
  V3Depth.o \
  V3DepthBlock.o \
  V3Descope.o \
  V3Dfg.o \
  V3DfgAstToDfg.o \
  V3DfgBreakCycles.o \
  V3DfgCache.o \
  V3DfgColorSCCs.o \
  V3DfgCse.o \
  V3DfgDataType.o \
  V3DfgDecomposition.o \
  V3DfgDfgToAst.o \
  V3DfgOptimizer.o \
  V3DfgPasses.o \
  V3DfgPeephole.o \
  V3DfgRegularize.o \
  V3DfgSynthesize.o \
  V3DiagSarif.o \
  V3DupFinder.o \
  V3EmitCMain.o \
  V3EmitCMake.o \
  V3EmitCModel.o \
  V3EmitCSyms.o \
  V3EmitMk.o \
  V3EmitMkJson.o \
  V3EmitXml.o \
  V3ExecGraph.o \
  V3Expand.o \
  V3Force.o \
  V3Fork.o \
  V3Gate.o \
  V3HierBlock.o \
  V3Inline.o \
  V3Inst.o \
  V3InstrCount.o \
  V3Interface.o \
  V3Life.o \
  V3LifePost.o \
  V3LinkCells.o \
  V3LinkDot.o \
  V3LinkInc.o \
  V3LinkJump.o \
  V3LinkLValue.o \
  V3LinkLevel.o \
  V3LinkParse.o \
  V3LinkResolve.o \
  V3Localize.o \
  V3MergeCond.o \
  V3Name.o \
  V3Order.o \
  V3OrderGraphBuilder.o \
  V3OrderMoveGraph.o \
  V3OrderParallel.o \
  V3OrderProcessDomains.o \
  V3OrderSerial.o \
  V3Param.o \
  V3Premit.o \
  V3ProtectLib.o \
  V3Randomize.o \
  V3Reloop.o \
  V3Sampled.o \
  V3Sched.o \
  V3SchedAcyclic.o \
  V3SchedPartition.o \
  V3SchedReplicate.o \
  V3SchedTiming.o \
  V3SchedTrigger.o \
  V3SchedUtil.o \
  V3SchedVirtIface.o \
  V3Scope.o \
  V3Scoreboard.o \
  V3Slice.o \
  V3Split.o \
  V3SplitAs.o \
  V3SplitVar.o \
  V3StackCount.o \
  V3Subst.o \
  V3TSP.o \
  V3Table.o \
  V3Task.o \
  V3Timing.o \
  V3Trace.o \
  V3TraceDecl.o \
  V3Tristate.o \
  V3Udp.o \
  V3Undriven.o \
  V3Unknown.o \
  V3Unroll.o \
  V3UnrollGen.o \
  V3Width.o \
  V3WidthCommit.o \
  V3WidthSel.o \

# verilator_coverage
VLCOV_OBJS = \
  VlcMain.o \

NON_STANDALONE_HEADERS = \
  V3AstAttr.h \
  V3AstInlines.h \
  V3AstNodeDType.h \
  V3AstNodeExpr.h \
  V3AstNodeOther.h \
  V3AstNodeStmt.h \
  V3DfgVertices.h \
  V3ThreadPool.h \
  V3WidthRemove.h \

AST_DEFS := \
  V3AstNodeDType.h \
  V3AstNodeExpr.h \
  V3AstNodeOther.h \
  V3AstNodeStmt.h \

DFG_DEFS := \
  V3DfgVertices.h

#### astgen common flags

ASTGENFLAGS = -I $(srcdir)
ASTGENFLAGS += $(foreach f,$(AST_DEFS),--astdef $f)
ASTGENFLAGS += $(foreach f,$(DFG_DEFS),--dfgdef $f)

#### Linking

ifeq ($(VL_VLCOV),)
  PREDEP_H = V3Ast__gen_forward_class_decls.h
  OBJS += $(RAW_OBJS) $(RAW_OBJS_PCH_ASTMT) $(RAW_OBJS_PCH_ASTNOMT)
else
  PREDEP_H =
  OBJS += $(VLCOV_OBJS)
endif

$(TGT): $(PREDEP_H) $(OBJS)
	@echo "      Linking $@..."
	${LINK} ${LDFLAGS} -o $@ $(OBJS) $(CCMALLOC) ${LIBS}

#### Modules

%__gen.cpp: %.cpp $(ASTGEN) $(AST_DEFS) $(DFG_DEFS)
	$(PYTHON3) $(ASTGEN) $(ASTGENFLAGS) $*.cpp

.SECONDARY:

%.gch: %
	$(OBJCACHE) ${CXX} ${CXXFLAGS} ${CXXFLAGSOBJ} ${CPPFLAGSWALL} ${CFG_CXXFLAGS_PCH} -c $< -o $@
%.o: %.cpp
	$(OBJCACHE) ${CXX} ${CXXFLAGS} ${CXXFLAGSOBJ} ${CPPFLAGSWALL} -c $< -o $@

V3ParseLex.o: V3ParseLex.cpp V3Lexer.yy.cpp V3ParseBison.c
	$(OBJCACHE) ${CXX} ${CXXFLAGS} ${CXXFLAGSOBJ} ${CPPFLAGSPARSER} -c $< -o $@

V3ParseGrammar.o: V3ParseGrammar.cpp V3ParseBison.c
	$(OBJCACHE) ${CXX} ${CXXFLAGS} ${CXXFLAGSOBJ} ${CPPFLAGSPARSER} -c $< -o $@

V3ParseImp.o: V3ParseImp.cpp V3ParseBison.c
	$(OBJCACHE) ${CXX} ${CXXFLAGS} ${CXXFLAGSOBJ} ${CPPFLAGSPARSER} -c $< -o $@

V3PreProc.o: V3PreProc.cpp V3PreLex.yy.cpp
	$(OBJCACHE) ${CXX} ${CXXFLAGS} ${CXXFLAGSOBJ} ${CPPFLAGSPARSER} -c $< -o $@

define CXX_ASTMT_template
$(1): $(basename $(1)).cpp V3PchAstMT.h.gch
	$(OBJCACHE) ${CXX} ${CXXFLAGS} ${CXXFLAGSOBJ} ${CPPFLAGSWALL} ${CFG_CXXFLAGS_PCH_I} V3PchAstMT.h${CFG_GCH_IF_CLANG} -c $(srcdir)/$(basename $(1)).cpp -o $(1)

endef

$(foreach obj,$(RAW_OBJS_PCH_ASTMT),$(eval $(call CXX_ASTMT_template,$(obj))))

define CXX_ASTNOMT_template
$(1): $(basename $(1)).cpp V3PchAstNoMT.h.gch
	$(OBJCACHE) ${CXX} ${CXXFLAGS} ${CXXFLAGSOBJ} ${CPPFLAGSWALL} ${CFG_CXXFLAGS_PCH_I} V3PchAstNoMT.h${CFG_GCH_IF_CLANG} -c $(srcdir)/$(basename $(1)).cpp -o $(1)

endef

$(foreach obj,$(RAW_OBJS_PCH_ASTNOMT),$(eval $(call CXX_ASTNOMT_template,$(obj))))

#### Generated files

# Target rule called before parallel build to make generated files
serial:: V3Ast__gen_forward_class_decls.h V3ParseBison.c

serial_vlcov:: vlcovgen.d

vlcovgen.d: $(VLCOVGEN) $(srcdir)/../include/verilated_cov_key.h
	$(PYTHON3) $(VLCOVGEN) --srcdir $(srcdir)
	touch $@

V3Ast__gen_forward_class_decls.h: $(ASTGEN) $(AST_DEFS) $(DFG_DEFS)
	$(PYTHON3) $(ASTGEN) $(ASTGENFLAGS) --classes

V3ParseBison.h: V3ParseBison.c

# Have only one output file in this rule to prevent parallel make issues
V3ParseBison.c: verilog.y $(BISONPRE)
	@echo "If you get errors from verilog.y below, try upgrading bison to version 1.875 or newer."
	$(PYTHON3) $(BISONPRE) --yacc ${YACC} -d -v -o V3ParseBison.c $(BISON_DEBUG) $<

V3Lexer_pregen.yy.cpp: verilog.l V3ParseBison.h $(HEADERS)
	${LEX} --version
	${LEX} ${LFLAGS} -o$@ $<

V3Lexer.yy.cpp: V3Lexer_pregen.yy.cpp $(FLEXFIX)
	$(PYTHON3) $(FLEXFIX) V3Lexer <$< >$@

V3PreLex_pregen.yy.cpp: V3PreLex.l $(HEADERS)
	${LEX} --version
	${LEX} ${LFLAGS} -o$@ $<

V3PreLex.yy.cpp: V3PreLex_pregen.yy.cpp $(FLEXFIX)
	$(PYTHON3) $(FLEXFIX) V3PreLex <$< >$@

# For t_dist_header_cc
HEADER_CC_H := $(filter-out $(NON_STANDALONE_HEADERS), $(notdir $(wildcard $(srcdir)/*.h)))

.PHONY: header_cc
header_cc: $(addsuffix __header_cc.o, $(basename $(HEADER_CC_H)))

%__header_cc.cpp: %.h
	$(PYTHON3) $(srcdir)/../bin/verilator_includer -DVL_MT_DISABLED_CODE_UNIT=1 $^ > $@

.SUFFIXES:

######################################################################
######################################################################

DEPS := $(wildcard *.d)
ifneq ($(DEPS),)
  include $(DEPS)
endif
